package com.ruoyi.business.service.impl;

import java.io.*;
import java.util.Collections;
import java.util.Date;
import java.util.List;

import com.ruoyi.common.config.SystemConfig;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.file.FileUploadUtils;
import org.activiti.bpmn.model.BpmnModel;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.image.impl.DefaultProcessDiagramGenerator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.business.mapper.BpmnInfoMapper;
import com.ruoyi.business.domain.BpmnInfo;
import com.ruoyi.business.service.IBpmnInfoService;
import com.ruoyi.common.core.text.Convert;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

/**
 * 流程定义明细Service业务层处理
 *
 * @author ruoyi
 * @date 2022-02-09
 */
@Service
@Transactional
public class BpmnInfoServiceImpl implements IBpmnInfoService {
    @Autowired
    private BpmnInfoMapper bpmnInfoMapper;
    @Autowired
    private RepositoryService repositoryService;

    /**
     * 查询流程定义明细
     *
     * @param id 流程定义明细主键
     * @return 流程定义明细
     */
    @Override
    public BpmnInfo selectBpmnInfoById(Long id) {
        return bpmnInfoMapper.selectBpmnInfoById(id);
    }

    /**
     * 查询流程定义明细列表
     *
     * @param bpmnInfo 流程定义明细
     * @return 流程定义明细
     */
    @Override
    public List<BpmnInfo> selectBpmnInfoList(BpmnInfo bpmnInfo) {
        return bpmnInfoMapper.selectBpmnInfoList(bpmnInfo);
    }

    /**
     * 新增流程定义明细
     *
     * @param bpmnInfo 流程定义明细
     * @return 结果
     */
    @Override
    public int insertBpmnInfo(BpmnInfo bpmnInfo) {
        return bpmnInfoMapper.insertBpmnInfo(bpmnInfo);
    }

    /**
     * 修改流程定义明细
     *
     * @param bpmnInfo 流程定义明细
     * @return 结果
     */
    @Override
    public int updateBpmnInfo(BpmnInfo bpmnInfo) {
        return bpmnInfoMapper.updateBpmnInfo(bpmnInfo);
    }

    /**
     * 批量删除流程定义明细
     *
     * @param ids 需要删除的流程定义明细主键
     * @return 结果
     */
    @Override
    public int deleteBpmnInfoByIds(String ids) {
        return bpmnInfoMapper.deleteBpmnInfoByIds(Convert.toStrArray(ids));
    }

    /**
     * 删除流程定义明细信息
     *
     * @param id 流程定义明细主键
     * @return 结果
     */
    @Override
    public int deleteBpmnInfoById(Long id) {
        return bpmnInfoMapper.deleteBpmnInfoById(id);
    }

    /**
     *bpmn文件上传和校验
     * @param file 文件存储对象
     * @return 返回路径
     */
    @Override
    public String upload(MultipartFile file) throws IOException {
        //通过文件上传工具类获取 拓展名
        String extension = FileUploadUtils.getExtension(file);
        if (!"bpmn".equalsIgnoreCase(extension)) {
            throw new ServiceException("文件上传仅支持bpmn格式!");
        }
        String upload = "";
        //SystemConfig.getProfile() 获取yml配置文件的计算机地址位置
        upload = FileUploadUtils.upload2(SystemConfig.getProfile(), file);
        return upload;
    }

    @Override
    public void deploy(String path, String bpmnType, String info) throws IOException {
        //获取之前上传的文件
        File file = new File(SystemConfig.getProfile(), path);
        //将文件部署到activiti7中
        FileInputStream inputStream = null;
        Deployment deploy = null;
        try {
            inputStream = new FileInputStream(file);
            deploy = repositoryService.createDeployment()
                    .addInputStream(path, inputStream)
                    .deploy();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        if (inputStream != null){
            inputStream.close();
        }

        //对其他内容进行更新
        BpmnInfo bpmnInfo = new BpmnInfo();
        bpmnInfo.setBpmnType(bpmnType);
        bpmnInfo.setDeployTime(new Date());
        bpmnInfo.setInfo(info);
        bpmnInfo.setDeploymentId(deploy.getId());//部署id
        //获取流程定义
        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
                .deploymentId(deploy.getId())
                .singleResult();
        bpmnInfo.setActProcessId(processDefinition.getId());//定义id
        bpmnInfo.setActProcessKey(processDefinition.getKey());
        //添加记录
        bpmnInfoMapper.insertBpmnInfo(bpmnInfo);
    }

    //根据id删除流程
    @Override
    public void delete(Long id) {
        BpmnInfo bpmnInfo = this.selectBpmnInfoById(id);
        String deploymentId = bpmnInfo.getDeploymentId();//部署id
        //TODO.查询所有流程实例更新流程实例
        bpmnInfoMapper.deleteBpmnInfoById(id);//删除当前部署记录
        //获取定义流程
        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
                .deploymentId(deploymentId)
                .singleResult();
        //删除流程定义
        repositoryService.deleteDeployment(deploymentId,true);
        //删除部署文件(resourceName资源名称)
        String resourceName = processDefinition.getResourceName();//获取资源名称
        File file = new File(SystemConfig.getProfile(), resourceName);
        if (file.exists()){
            file.delete();
        }
    }

    /**
     * 根据部署id 和 类型查询 内容
     * @param deploymentId 部署流程id
     * @param type 类型
     * @return 返回内容流
     */
    @Override
    public InputStream getResoucceByType(String deploymentId, String type) {
        InputStream inputStream = null;
        //获取流程定义
        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
                .deploymentId(deploymentId)
                .singleResult();
        if ("xml".equalsIgnoreCase(type)){
            //获取xml文件
            String resourceName = processDefinition.getResourceName();//获取资源名称
            inputStream = repositoryService.getResourceAsStream(deploymentId, resourceName);
        }
        if ("png".equalsIgnoreCase(type)){
            //获取bpmn模型
            BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinition.getId());
            //创建插件对象
            DefaultProcessDiagramGenerator generator = new DefaultProcessDiagramGenerator();
            //generateDiagram(bpmn模型,需要高亮的节点ID集合,需要高亮的联线id集合)
            inputStream = generator.generateDiagram(bpmnModel,
                    Collections.EMPTY_LIST,
                    Collections.EMPTY_LIST,
                    "微软雅黑",
                    "微软雅黑",
                    "微软雅黑");//解决乱码
        }

        return inputStream;
    }

    /**
     * 根据类型查找数据
     * @param car_package 类型
     * @return 返回符合单个类型的数据
     */
    @Override
    public BpmnInfo getByBpmnType(String car_package) {
        return bpmnInfoMapper.getByBpmnType(car_package);
    }
}
